import window from '@ohos.window'
import JsLogger from './JsLogger'
import display from '@ohos.display';
import JsDataStore from './JsDataStore'

export class JsWindow {

    private name: string;
    private window: window.Window = undefined;
    private rect: window.Rect;

    constructor(name: string, window: window.Window) {
        this.name = name;
        this.window = window;
        this.window?.on("windowSizeChange", (size)=>{
            JsLogger.info("%{public}s window size changed %{public}d %{public}d", name, size.width, size.height);
            let d = display.getDefaultDisplaySync();
            // JsDataStore.getQtNativeModule("QPA").handleGeometryChange(name, p.windowRect.left, p.windowRect.top, size.width, size.height);
            JsDataStore.getQtNativeModule("QPA").setDisplayMetrics(size.width, size.height, d.densityDPI, d.scaledDensity, d.xDPI, d.yDPI,
                0, 0, size.width, size.height);
            JsDataStore.getQtNativeModule("QPA").handleGeometryChange(name, 0, 0, size.width, size.height);
        });
    }

    async setGeometry(x: number, y: number, w: number, h: number): Promise<boolean> {
        JsLogger.info('set window geometry: %{public}s %{public}d %{public}d %{public}d %{public}d', x, y, w, h)
        try {
            if (this.window != undefined) {
                let visible = this.window.isWindowShowing();
                if (visible) {
                    await this.window.moveWindowTo(x, y);
                    await this.window.resize(w, h);
                }
                this.rect = {'width': w, 'height': h, 'left': x, 'top': y}
            }
            return true;
        } catch (exception) {
            JsLogger.error('Failed to call setGeometry for the Window %{public}s. Cause: %{public}s', this.name, JSON.stringify(exception));
            return false;
        }
    }

    async destroyWindow() : Promise<boolean> {
        try {
            await this.window.destroyWindow();
            return true;
        } catch (exception) {
            JsLogger.error('Failed to call destroyWindow for the Window %{public}s. Cause: %{public}s', this.name, JSON.stringify(exception));
            return false;
        }
    }

    async setVisible(visible: boolean): Promise<boolean> {
        JsLogger.error("set window visible: %{public}s %{public}s", this.name, visible);
        try {
            if (this.window != undefined) {
                if (visible) {
                    await this.window.showWindow();
                    await this.window.moveWindowTo(this.rect.left, this.rect.top);
                    await this.window.resize(this.rect.width, this.rect.height);
                } else {
                    this.hideWindow();
                }
            }
            return true;
        } catch (exception) {
            JsLogger.error('Failed to call showWindow for the Window. Cause: %{public}s', JSON.stringify(exception));
            return false;
        }
    }

    async hideWindow() : Promise<void>  {
        let d = display.getDefaultDisplaySync();
        // 由于鸿蒙没有对外提供hide接口，把窗口移到屏幕之外去
        await this.window.moveWindowTo(d.width + 50, d.height + 50);
    }

    async load() : Promise<void> {
        let store = new LocalStorage({"name": this.name});
        await this.window.loadContent('pages/Index', store);
        // 如果不显示窗口，xcompoent不会创建，导致c++端等待失败。
        await this.setVisible(true);
        this.hideWindow();
    }
}
